package com.ksyun.campus.client;

import com.ksyun.campus.client.domain.ApiResponse;
import com.ksyun.campus.client.domain.ReplicaData;
import com.ksyun.campus.client.domain.dto.ReadDTO;
import com.ksyun.campus.client.domain.dto.WriteContentDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


@Data
@Slf4j
public class FSInputStream extends InputStream {

    List<ReplicaData> replicaDataList;

    private RestTemplate restTemplate=new RestTemplate();

    public FSInputStream(List<ReplicaData> replicaDataList) {
        this.replicaDataList = replicaDataList;
    }


    @Override
    public int read() throws IOException {
        throw new UnsupportedOperationException();
    }

    @Override
    public int read(byte[] b) throws IOException {
        return this.read(b,0,b.length);
    }

    @Override
    public int read(byte[] b, int off, int len) throws IOException {
        if (b == null) {
            throw new NullPointerException();
        } else if (off < 0 || len < 0 || len > b.length - off) {
            throw new IndexOutOfBoundsException();
        } else if (len == 0) {
            return 0;
        }
        byte[] data=null;//用于保存读取的数据

        boolean dataRead = false; // 标识是否已成功读取数据

        // 重试机制，保证只请求一个节点即可
        for (int i = 0; i < replicaDataList.size(); i++) {
            ReplicaData replicaData = replicaDataList.get(i);
            String dsNode = replicaData.getDsNode();
            String path = replicaData.getPath();
            String dsURL = "http://" + dsNode + "/read";
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.APPLICATION_JSON);
            ReadDTO readDTO = new ReadDTO();
            readDTO.setPath(path);
            readDTO.setOffset(off);
            readDTO.setLength(len);
            HttpEntity<ReadDTO> request = new HttpEntity<>(readDTO, header);

            try {
                ResponseEntity<byte[]> response = restTemplate.exchange(
                        dsURL,
                        HttpMethod.POST,
                        request,
                        byte[].class
                );
                data = response.getBody();
                if (data !=null){
                    dataRead=true;
                    break;
                }
            } catch (Exception e) {
                // 请求失败，记录已经尝试的节点索引
                log.info("结点未读取数据成功，寻找下一个副本节点");
            }
        }

        if (dataRead) {
            System.arraycopy(data, 0, b, off, data.length);
            return data.length;
        } else {
            return 0;
        }
    }

    @Override
    public void close() throws IOException {
        super.close();
    }
}
